<template>
  <el-table v-loading="loading" :data="tableData" table-layout="auto" style="width:100%" @selection-change="handleSelectionChange" :header-cell-style="headSearch">
    <el-table-column type="selection" />
    <el-table-column prop="fileName" label="FileName">
      <template #default="{ row }">
        <el-tooltip class="box-item" effect="dark" content="点击文件名即可下载文件" placement="right">
          <span class="fileName" @click="handleDownload(row)">{{ row.fileName }}</span>
        </el-tooltip>
      </template>
    </el-table-column>
    <el-table-column align="right" v-if="smallHide" prop="fileSize" label="Size" :formatter="formatFileSize" width="100">
    </el-table-column>
    <el-table-column align="center" v-if="smallHide" prop="createTime" label="CreateTime" :formatter="dateFormat" width="200">
    </el-table-column>
    <el-table-column fixed="right" align="center" label="Operations" :width="operationsColumnWidth" class-name="ops-cell">
      <template #header>
        <div class="search-input">
          <el-input v-model="qureyParam.searchValue" size="small" placeholder="Type to search" @keyup.enter.native="getFileList" />
          <el-button :size="buttonSize" :icon-only="!isTextVisible" :icon="Search" id="search-button" @click="getFileList">{{ buttonText }}
          </el-button>
        </div>
      </template>
      <template #default="{ $index, row }">
        <div class="ops-group">
          <el-button text type="info" size="small" :icon="View" @click="handlePreview($index, row)">Preview</el-button>
          <el-button text size="small" type="warning" @click="openRenameDialog(row)">Rename</el-button>
          <el-button class="btn" text type="primary" size="small" :icon="Link" @click="handleShare($index, row)" :data-clipboard-text="currentShareLink">Share</el-button>
          <el-button text type="danger" size="small" :icon="Delete" @click="handleDelete($index, row)">Delete</el-button>
        </div>
      </template>

    </el-table-column>
  </el-table>
  <el-row :gutter="10" class="mb8">
    <el-col :span="1.5">
      <el-tooltip class="box-item" effect="dark" content="删除所选记录和文件" placement="right">
        <el-button type="danger" :icon="Delete" size="default" :disabled="batchDelete" @click="handleBatchDelete">
          {{ batchDeleteText }}
        </el-button>
      </el-tooltip>

    </el-col>
    <el-col :span="1.5" class="el-pagination">
      <el-pagination v-model="currentPage" :page-size="pageSize" :pager-count="pagerCount" :layout="pageLayout" :total="total || 0" @size-change="handleSizeChange" @current-change="handleCurrentChange"></el-pagination>
    </el-col>
  </el-row>
  <el-backtop :right="100" :bottom="100" />
    <!-- 图片预览对话框 -->
    <el-dialog  v-model="previewVisible" title="图片预览" width="50%">
    <el-image :src="previewImageUrl" fit="contain" style="width: 100%; height: auto;"></el-image>
  </el-dialog>

  <!-- 重命名对话框 -->
  <el-dialog v-model="renameVisible" title="重命名文件" width="480px">
    <el-form @submit.prevent>
      <el-form-item label="新文件名">
        <el-input v-model="renameForm.newName" maxlength="255" show-word-limit placeholder="请输入新的文件名"></el-input>
      </el-form-item>
    </el-form>
    <template #footer>
      <el-button @click="renameVisible = false">取消</el-button>
      <el-button type="primary" :loading="renaming" @click="confirmRename">确定</el-button>
    </template>
  </el-dialog>
</template>

<script>

import { getFiles, deleteFile, exitsFile, renameFile } from '../apis/files'
import { Delete, Link, Search, View } from '@element-plus/icons-vue'
import Clipboard from 'clipboard'
import { ElMessage, ElMessageBox } from 'element-plus'

export default {
  computed: {
    Delete() {
      return Delete
    },
    Link() {
      return Link
    },
    Search() {
      return Search
    },
    operationsColumnWidth() {
      // PC端适配三按钮并排；移动端更小
      if (this.windowWidth >= 1400) return 280
      if (this.windowWidth >= 1200) return 260
      if (this.windowWidth >= 992) return 240
      if (this.windowWidth >= 768) return 200
      return 140
    }
  },
  components: { Delete, Link, View },
  data() {
    return {
      loading: true,
      currentPage: 1,
      pageSize: 20,
      total: 0,
      qureyParam: {
        pageNum: 1,
        pageSize: 20,
        searchValue: null // 正确的axios参数形式，axios能正确处理null.否则不要定义成null，定义成空字符串就可以避免，将字符串转成了"null"到了后端。
      },
      tableData: [],
      deleteIds: [],
      batchDelete: true,
      currentShareLink: null,
      isTextVisible: true,
      buttonText: 'Search',
      batchDeleteText: "批量删除",
      buttonSize: 'default',
      windowWidth: document.documentElement.clientWidth,  //实时屏幕宽度
      smallHide: true,
      pageLayout: "prev,pager,next,jumper,sizes,total",
      pagerCount:5,
      previewVisible: false,
      previewImageUrl: '',
      renameVisible: false,
      renaming: false,
      renameForm: { id: null, fileUuid: '', newName: '' }
    }
  },
  watch: {
    isBatchDelete() {
      console.log('监听变化' + batchDelete)
      return true
    },
    windowWidth(val) {
      let that = this;
      that.windowWidth = document.documentElement.clientWidth
      console.log("实时屏幕宽度：", val, that.windowWidth);
    }
  },
  created() {
  },
  activated() {
    // 组件被 keep-alive 缓存后，每次激活时重新拉取最新数据
    this.getFileList()
  },
  methods: {
    updateButtonTextVisibility() {
      if (window.innerWidth < 768) {
        // Hide button text when screen width is less than 768px
        this.isTextVisible = false
        this.buttonText = ''
        this.batchDeleteText = ''
        this.buttonSize = 'small'
      } else {
        // Show button text when screen width is greater than or equal to 768px
        this.isTextVisible = true
        this.buttonText = 'Search'
        this.batchDeleteText = '批量删除'
        this.buttonSize = 'default'
      }
    },
    handleSizeChange(val) {
      this.pageSize = val
      this.qureyParam.pageSize = val
      this.getFileList()
    },
    handleCurrentChange(val) {
      this.currentPage = val
      this.qureyParam.pageNum = val
      this.getFileList()
    },
    handleShare(index, row) {

      console.log('分享链接', index, row)

      // 获取当前页面地址，如http://localhost:8080/admin/index
      let wPath = window.document.location.href
      console.log('当前URL ' + wPath)
      // 获取当前页面主机地址之后的目录，如：/admin/index
      let pathName = this.$route.path
      console.log('当前pathName ' + pathName)
      let pos = wPath.lastIndexOf(pathName)
      console.log('当前pathName位置  ' + pos)
      // 获取主机地址，如：http://localhost:8080
      let localhostPath = wPath.substring(0, pos)
      localhostPath = localhostPath.replace('#', '')
      console.log('当前localhostPath位置  ' + localhostPath)
      this.currentShareLink = localhostPath + 'api/file/download?fileUuid=' + row.fileUuid

      //实例化clipboard插件实例
      let clipboard = new Clipboard('.btn')
      //成功的回调
      clipboard.on('success', () => {
        // ElMessage({
        //   message: '已复制到粘贴板',
        //   type: 'success'
        // })
        ElMessage.success('已复制到粘贴板')
        clipboard.destroy()// 销毁复制缓存,避免出现复制之前复制的内容
      })
      //失败的回调
      clipboard.on('error', () => {
        // ElMessage({
        //   message: '复制到粘贴板失败',
        //   type: 'error'
        // })
        ElMessage.error('复制到粘贴板失败')
      })

    },
    handleDelete(index, row) {
      console.log('删除文件', index, row)
      deleteFile(row.id).then((resp) => {
        if (resp.code == 200) {
          ElMessage({
            message: '删除文件成功',
            type: 'success'
          })
          this.getFileList()
        } else {
          ElMessage({
            message: '删除文件失败',
            type: 'warning'
          })
        }
      })
    },
    handleBatchDelete() {
      console.log('批量删除文件')
      if (this.deleteIds != null && this.deleteIds != undefined && this.deleteIds.length > 0) {
        deleteFile(this.deleteIds).then((resp) => {
          if (resp.code == 200) {
            ElMessage({
              message: '删除文件成功',
              type: 'success'
            })
            this.getFileList()
          } else {
            ElMessage({
              message: '删除文件失败',
              type: 'warning'
            })
          }
        })
      }
    },
    handleSelectionChange(val) {
      if (val != null && val != undefined && val.length > 0) {
        this.deleteIds = [] // 解决批量选择后，去掉某些值之后的重新赋值
        console.log('全选', val)
        this.batchDelete = false
        for (let i = 0; i < val.length; i++) {
          this.deleteIds.push(val[i].id)
        }
      } else {
        console.log('全选取消', val)
        this.batchDelete = true
      }

    },
    getFileList() {
      this.loading = true
      getFiles(this.qureyParam).then((res) => {
        // 注意 不是使用 + 来连接，使用 + 连接之后就无法显示（只显示 [object Object]【其实就是相当于Object.toString()了，所以没法查看】，无法点击查看。）。使用逗号，方便显示。
        console.log('加载的数据 ', res)
        this.tableData = res.data.records
        this.total = res.data.total
      }).finally(() => {
        this.loading = false
      })
    },
    openRenameDialog(row) {
      this.renameForm = { id: row.id, fileUuid: row.fileUuid, newName: row.fileName }
      this.renameVisible = true
      this.$nextTick(() => {
        try { document.querySelector('.el-dialog input')?.focus() } catch (_) {}
      })
    },
    async confirmRename() {
      const name = (this.renameForm.newName || '').trim()
      if (!name) {
        ElMessage.warning('新文件名不能为空')
        return
      }
      this.renaming = true
      try {
        const resp = await renameFile({ id: this.renameForm.id, fileUuid: this.renameForm.fileUuid, newName: name })
        if (resp?.code === 200) {
          ElMessage.success('重命名成功')
          this.renameVisible = false
          this.getFileList()
        } else {
          ElMessage.error(resp?.msg || '重命名失败')
        }
      } catch (e) {
        ElMessage.error('重命名失败')
      } finally {
        this.renaming = false
      }
    },
    // 下载文件时的钩子
    handleDownload(file) {

      var param = {
        'uuid': file.fileUuid
      }

      exitsFile(param).then((res) => {
        if (res.code == 200) {
          ElMessage({
            message: '正在下载，请稍后',
            type: 'success'
          })
          // 查看点击事件后传递过来的数据
          console.log(file, '下载文件事件')
          // 创建 a 标签
          const a = document.createElement('a')
          // 创建一个点击事件
          const event = new MouseEvent('click')
          // 将 a 的 download 属性设置为我们想要下载的图片的名称，若 name 不存在则使用'图片'作为默认名称
          a.download = file.fileName || '文件名称'
          // 将生成的 url 设置为 a.href 属性 （file.downloadUrl 属性也是一个链接，是一个自定义的链接）
          a.href = 'api/file/download?fileUuid=' + file.fileUuid
          // 打开新的窗口（如果是一个图片类型的文件，在浏览器打开新的标签页打开）
          a.target = '_blank'
          // 实现触发生成的 a 标签
          a.dispatchEvent(event)
        } else {
          ElMessage({
            message: res.msg,
            type: 'warning'
          })
        }
      })
    },
    formatFileSize(row) {
      let fileSize = row.fileSize
      if (fileSize < 1024) {
        return fileSize + 'B'
      } else if (fileSize < (1024 * 1024)) {
        var temp = fileSize / 1024
        temp = temp.toFixed(2)
        return temp + 'KB'
      } else if (fileSize < (1024 * 1024 * 1024)) {
        var temp = fileSize / (1024 * 1024)
        temp = temp.toFixed(2)
        return temp + 'MB'
      } else {
        var temp = fileSize / (1024 * 1024 * 1024)
        temp = temp.toFixed(2)
        return temp + 'GB'
      }
    },
    dateFormat(row) {
      var dt = new Date(row.createTime)
      let year = dt.getFullYear()
      let month = (dt.getMonth() + 1).toString().padStart(2, '0')
      let date = dt.getDate().toString().padStart(2, '0')
      let hour = dt.getHours().toString().padStart(2, '0')
      let minute = dt.getMinutes().toString().padStart(2, '0')
      let second = dt.getSeconds().toString().padStart(2, '0')
      return `${year}-${month}-${date} ${hour}:${minute}:${second}`
    },
    headSearch({ row, colunm, rowIndex, columnIndex }) {
      // 仅根据屏幕宽度切换小屏显示的列与分页样式，不再做表头跨列合并，避免遮挡文件名
      if (document.documentElement.clientWidth > 768) {
        this.smallHide = true
        this.pagerCount = 5
        this.pageLayout = "prev,pager,next,jumper,sizes,total"
      } else {
        this.smallHide = false
        this.pagerCount = 2
        this.pageLayout = "prev,pager,next,total"
      }
      return {}
    },
    handlePreview(index, row) {

      console.log('图片预览1', index, row)

      // 获取当前页面地址，如http://localhost:8080/admin/index
      let wPath = window.document.location.href
      console.log('当前URL ' + wPath)
      // 获取当前页面主机地址之后的目录，如：/admin/index
      let pathName = this.$route.path
      console.log('当前pathName ' + pathName)
      let pos = wPath.lastIndexOf(pathName)
      console.log('当前pathName位置  ' + pos)
      // 获取主机地址，如：http://localhost:8080
      let localhostPath = wPath.substring(0, pos)
      localhostPath = localhostPath.replace('#', '')
      console.log('当前localhostPath位置  ' + localhostPath)
      this.previewImageUrl = localhostPath + 'api/file/download?fileUuid=' + row.fileUuid

      // 处理预览逻辑
      this.previewVisible = true;
    }
  },
  mounted() {
    // 第一种监控屏幕大小的方法
    this.updateButtonTextVisibility()
    window.addEventListener('resize', this.updateButtonTextVisibility)

    // 第二种监控屏幕大小的方法
    var that = this;
    window.onresize = () => {
      return (() => {
        window.fullWidth = document.documentElement.clientWidth;
        that.windowWidth = window.fullWidth; // 宽
      })()
    };
  }

}
</script>

<style lang="scss">
.el-row {
  margin-top: 10px;
}

.el-pagination {
  padding-right: 10px;
  margin-left: auto;
}

.el-table {
  .fileName:hover {
    color: #409eff !important;
  }
}

.search-input {
  display: flex;
}

#search-button {
  margin-left: 5px;
}

/* 让PC端操作列三按钮并排不换行 */
.el-table .ops-cell .cell {
  white-space: nowrap;
}

/* 按钮组：PC 横排，移动端纵向堆叠 */
.ops-group {
  display: inline-flex;
  gap: 10px;
}

@media (max-width: 767px) {
  /* 移动端允许换行并改为纵向布局 */
  .el-table .ops-cell .cell {
    white-space: normal;
  }
  .ops-group {
    display: inline-flex;
    flex-direction: column;
    gap: 4px;
  }
}
</style>
